#include "algorithm.h"

using namespace std;

//Setters for the width and height members
void algorithm::setWidth(int w)
{
	width = w;
}

void algorithm::setHeight(int h)
{
	height = h;
}


//Allocates memory for a new node
Node* algorithm::allocateNode(int x, int y)
{
	Node* n = new Node (x, y);
	if (pmap == 0)
	{
		cout << "Error: memory could not be allocated";
		return 0;
	}
	
	return n;
}


//Print the path founded from the start to the goal
results* algorithm::createResults(Node* n, const type_info& type, string a, double diffticks)
{
	//Create a pointer to results to store the solution in there
	results* res = new results;

	//If a solution has been found, create a vector of coordinates and generate it 
	//browsing the nodes from the goal to the start
	if(n)
	{
		//Store the cost of the path
		res->setCost(n->getF());

		vector<coord>* coordinates = new vector<coord>(0);
		coordinates->reserve(10);
		while(n != 0)
		{
			coordinates->push_back(coord(n->getX(), n->getY()));
			n = n->getParent();
		}

		//Set the coordinates member of results
		res->setCoordinates(coordinates);
	}
	else
	{
		res->setCost(0);
		res->setCoordinates(0);
	}

	//Set the algorithm used
	res->setAlgorithm(a);

	//Set the data structure used
	if(type == typeid(unsortedVector)) res->setDataStructure("Unsorted Vector");
	else if(type == typeid(sortedVectorByF)) res->setDataStructure("Sorted Vector by Cost");
	else if(type == typeid(sortedVectorByXY)) res->setDataStructure("Sorted Vector by coordinates");
	else if(type == typeid(skipList)) res->setDataStructure("Skip List");
	else if(type == typeid(hashTable)) res->setDataStructure("Hash Table");
	else if(type == typeid(hashTableSortedVector)) res->setDataStructure("Hash Table with Sorted Vector by Cost");

	//Set the number of nodes visited
	res->setVisitedNodes(visitedNodes);

	//Set the execution time
	res->setExecutionTime(diffticks);

	//Set the execution time of the add method
	res->setAdd(add);

	//Set the execution time of the remove method
	res->setModify(modify);

	//Set the execution time of the selectLowest method
	res->setSelectLowest(selectLowest);

	//Set the execution time of the find method
	res->setFind(find);

	return res;
}


//Generates and returns a pointer to a vector of pairs of integers which are the coordinates of the
//successors of the node passed as argument
vector<coord>* algorithm::getSuccessors(Node* node)
{
	//Create the structure that will store the coordinates of the successors
	vector<coord>* successors = new vector<coord>(0);
	successors->reserve(4);

	int x = node->getX();
	int y = node->getY();
	Node* parent = node->getParent();	

	//Check the successor at the left
	if(x-1 >= 0 && (parent == 0 || parent->getX() != x-1) && *(pmap + x-1 + y*width) != 4) successors->push_back(coord(x-1, y));

	//Check the successor at the right
	if(x+1 < width && (parent == 0 || parent->getX() != x+1) && *(pmap + x+1 + y*width) != 4) successors->push_back(coord(x+1, y));

	//Check the successor at the top
	if(y-1 >= 0 && (parent == 0 || parent->getY() != y-1) && *(pmap + x + (y-1)*width) != 4) successors->push_back(coord(x, y-1));

	//Check the successor at the bottom
	if(y+1 < height && (parent == 0 || parent->getY() != y+1) && *(pmap + x + (y+1)*width) != 4) successors->push_back(coord(x, y+1));

	return successors;
}